package com.auto.survey.activity.monitoring

import android.content.Intent
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.auto.survey.R
import com.auto.survey.activity.bluetooth.BluetoothManagerUtil
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_OBJECT_ID
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_PROJET_ID
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_STATION_ID
import com.auto.survey.activity.monitoring.adapter.AutoCheckAdapter
import com.auto.survey.activity.monitoring.dao.MonitoringRepository
import com.auto.survey.activity.monitoring.entity.MonitorCheckPoint
import com.auto.survey.activity.monitoring.entity.MonitorStauts
import com.auto.survey.activity.monitoring.entity.relations.PointWithCheckedPoint
import com.auto.survey.activity.monitoring.modle.AutoCheckViewModle
import com.auto.survey.base.BaseActivity
import com.auto.survey.base.CustomApplication
import com.auto.survey.geocom.CommandContext
import com.auto.survey.geocom.GeoCom
import com.auto.survey.geocom.GeoComCommon
import com.auto.survey.geocom.GeoComHelper
import com.auto.survey.util.Helper
import com.auto.survey.util.taskqueue.BluetoothTask
import com.auto.survey.util.taskqueue.BluetoothTaskListener
import com.auto.survey.util.taskqueue.BluetoothTaskQueue
import com.auto.survey.util.taskqueue.BluetoothTaskResult
import com.auto.survey.widget.CentreToast
import com.auto.survey.widget.dialog.loadingdialog.LoadingDialog
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.math.absoluteValue

class AutoCheckActivity:BaseActivity() {

    private var projectId:Int = -1
    private var objectId:Int = -1
    private var stationId:Int = -1
    private val database = MonitoringRepository()
    private val bluetoothManager by lazy { BluetoothManagerUtil.getInstance(this) }
    private val geoComHelper: GeoComHelper by lazy { GeoComHelper.getInstance(bluetoothManager) }
    private var isBluetoothConnected = false
    private lateinit var mAdapter :AutoCheckAdapter
    private val viewModel: AutoCheckViewModle by viewModels()
    private lateinit var monitorStauts: MonitorStauts
    private lateinit var monitorCheckPoint:MonitorCheckPoint
    // 创建并显示加载框
    private var loadingDialog: LoadingDialog?= null

    private lateinit var items: List<PointWithCheckedPoint>

    private var prismType = "-1"    //当前测量的模式
    // 初始化蓝牙任务队列
    private val bluetoothQueue = BluetoothTaskQueue<String>()
    // 单例回调对象
    private var geoComCallback: ((List<GeoCom>,CommandContext) -> Unit)? = null
    private var currentContinuation: CancellableContinuation<BluetoothTaskResult>? = null
    private var isResumed = AtomicBoolean(false) // 使用原子变量确保线程安全

    override fun initView() {
        projectId = intent.getIntExtra(KEY_INTENT_PROJET_ID, -1)
        objectId = intent.getIntExtra(KEY_INTENT_OBJECT_ID, -1)
        stationId = intent.getIntExtra(KEY_INTENT_STATION_ID, -1)

        monitorStauts = MonitorStauts()


        mTopBar?.visibility = View.VISIBLE
        mTopBar?.setBackgroundResource(R.color.action_bar)

        mComment_title?.visibility = View.VISIBLE
        mComment_title?.setBackgroundResource(R.color.action_bar)
        mComment_title?.setTitle("自动核验")

        loadingDialog = LoadingDialog(this)

        val stateTv:TextView = findViewById(R.id.tv_autocheck_state)
        val modleTv:TextView = findViewById(R.id.tv_aoutcheck_measuretModle)
        val mirrorTv:TextView = findViewById(R.id.tv_mirror_type)

        findViewById<TextView>(R.id.tv_begin_autochecked).setOnClickListener {
            if (!monitorStauts.pass()) {
                CentreToast.instance.show("当前仪器状态异常，请检查仪器状态", false)
                return@setOnClickListener
            }

            if (items.isNotEmpty()) {
                val mutableList = items.toMutableList()
                doCheckedExecut(mutableList)

            }
        }

        findViewById<TextView>(R.id.tv_reset_autochecked).setOnClickListener {
           val intent = Intent()
            intent.putExtra(KEY_INTENT_PROJET_ID, projectId)
            intent.putExtra(KEY_INTENT_OBJECT_ID, objectId)
            intent.putExtra(KEY_INTENT_STATION_ID, stationId)
            intent.setClass(this@AutoCheckActivity, AutoCheckHistoryActivity::class.java)
            startActivity(intent)
        }

        val rv = findViewById<RecyclerView>(R.id.rv_checklist)
        rv.layoutManager = LinearLayoutManager(this)
        mAdapter = AutoCheckAdapter()
        rv.adapter = mAdapter
        mAdapter.setOnAdapterClick(object : AutoCheckAdapter.AutoCheckAdapterClickListener{
            override fun onResetCheckStauts(position: Int, item: PointWithCheckedPoint) {
                CentreToast.instance.showText("重置")
            }

            override fun onStartCheck(position: Int, item: PointWithCheckedPoint) {
                CentreToast.instance.showText("从此开始")
            }

            override fun commonCheck(position: Int, item: PointWithCheckedPoint) {
                CentreToast.instance.showText("手动")
            }

        })


        if (bluetoothManager.isBluetoothConnected()) {
            isBluetoothConnected = true
            geoComHelper.startExecution(listOf( GeoComCommon.TMC_GetInclineSwitch,
                GeoComCommon.TMC_GetAngSwitch,GeoComCommon.BAP_GetPrismType,
                GeoComCommon.TMC_GetEdmMode, GeoComCommon.TMC_GetAngle1))
        }


        geoComHelper.onConnectionStateChanged { device, state ->
            if (bluetoothManager.isBluetoothConnected()) {
                CentreToast.instance.show("设备连接成功", true)
                isBluetoothConnected = true

                geoComHelper.startExecution(listOf( GeoComCommon.TMC_GetInclineSwitch,
                    GeoComCommon.TMC_GetAngSwitch,GeoComCommon.BAP_GetPrismType,
                    GeoComCommon.TMC_GetEdmMode, GeoComCommon.TMC_GetAngle1))

            } else {
                isBluetoothConnected = false
            }
        }

        lifecycleScope.launch {
            viewModel.state.observe(this@AutoCheckActivity) {
                stateTv.text = it.getStauts()
            }

            viewModel.mirrorType.observe(this@AutoCheckActivity) {
                mirrorTv.text = it
            }

            viewModel.measureModle.observe(this@AutoCheckActivity) {
                modleTv.text = it
            }

            viewModel.mupdata.observe(this@AutoCheckActivity) {
                mAdapter.setData(it)
            }

        }

        // 初始化单例回调（如果尚未初始化）
        initGeoComCallback()

        // 注册回调（如果尚未注册）
        if (geoComCallback != null && !geoComHelper.isRegisterCallback(geoComCallback!!)) {
            geoComHelper.resultCallback(geoComCallback!!)
        }
    }

    override fun onResume() {
        super.onResume()
        lifecycleScope.launch {
            database.getCollectedPointsWithCheckedPointsByStationId(stationId).collect{
                items = it
                mAdapter.setData(it)
            }
        }
    }

    private fun doCheckedExecut(mutableList:List<PointWithCheckedPoint>) {
        bluetoothQueue.setListener(object : BluetoothTaskListener<String>{

            override fun onTaskStarted(taskId: String) {
                // 任务开始：更新UI（如显示"正在执行任务XXX"）
                loadingDialog?.show()
                Log.d("AutoCheckActivity", "任务 $taskId 开始执行")
                monitorCheckPoint = MonitorCheckPoint(pointId = taskId.toInt(),
                    checkPointX = 0.0,
                    checkPointY=0.0,
                    checkPointZ=0.0,
                    checkPointHz=0.0,
                    checkPointV=0.0,
                    checkPointSD=0.0,
                    isChecked=false,
                    createTime = "",
                    isPass=false,
                    isNew = true)
            }

            override fun onTaskFailed(taskId: String, reason: String) {
                Log.e("AutoCheckActivity", "任务 $taskId 执行失败：$reason")
            }

            override fun onTaskSuccess(taskId: String, params: Map<String, Any>) {
                // 任务成功：更新UI（如显示"任务XXX成功"
                Log.d("AutoCheckActivity", "任务 $taskId 执行成功")
                viewModel.updateMonitorCheckPoint(monitorCheckPoint, database, stationId)
            }

            override fun onQueueCompleted() {
                // 所有任务完成：更新UI（如显示"全部任务执行完成"）
                Log.d("AutoCheckActivity", "队列中所有任务执行完成")
                loadingDialog?.dismiss()
            }

            override fun onQueueAborted(lastFailedTaskId: String, reason: String) {
                // 队列终止：更新UI（如显示"任务XXX失败，队列终止"）
                Log.e("AutoCheckActivity", "队列终止，最后失败的任务：$lastFailedTaskId，原因：$reason")
                loadingDialog?.dismiss()
            }
        })
        mutableList.forEach { withCheckPoint ->
            val taskid = withCheckPoint.point.id.toString()
            bluetoothQueue.addBluetoothTask(taskid, createBluetoothTask(withCheckPoint))
        }
    }


    private fun createBluetoothTask(withCheckPoint: PointWithCheckedPoint): BluetoothTask {

        return suspend {
            suspendCancellableCoroutine { continuation ->
                // 重置状态
                isResumed.set(false)
                currentContinuation = continuation

                try {

                    // 启动初始任务
                    geoComHelper.startExecution(listOf(
                        GeoComCommon.AUT_MakePositioning(
                            withCheckPoint.point.pointHz.toString(),
                            withCheckPoint.point.pointV.toString()
                        )
                    ))


                    // 处理协程取消
                    continuation.invokeOnCancellation {
                        if (isResumed.compareAndSet(false, true)) {
                            currentContinuation = null
                        }
                    }

                } catch (e: Exception) {
                    safeResumeWithFailure("未知错误: ${e.message}")
                }
            }
        }
    }

    // 初始化回调函数
    private fun initGeoComCallback() {
        if (geoComCallback == null) {
            geoComCallback = { results, params->
                results.forEach { result ->
                    Log.i("AutoCheckActivity", "name = ${result.name}, command=${result.command}, result=${result.result}")
                    when (result.name) {
                        GeoComCommon.TMC_GetInclineSwitch.name->{
                            if (CustomApplication.isAppInForeground) {
                                val list = Helper.parseJson(result.result)
                                if ("1" != list[1]){
                                    monitorStauts.getInclineSwitch = false
                                } else {
                                    monitorStauts.getInclineSwitch = true
                                }
                                viewModel.updateState(monitorStauts)
                            }
                        }

                        GeoComCommon.TMC_GetAngSwitch.name->{
                            val list = Helper.parseJson(result.result)
                            val inClineCorr     = list[1]   //倾斜校正状态
                            val standAxisCorr   = list[2]   //竖轴校正状态
                            val collimationCorr = list[3]   //视准轴校正状态
                            val tiltaxisCorr    = list[4]   //横轴校正状态

                            if ("1" != inClineCorr){
                                monitorStauts.inClineCorr = false
                            } else {
                                monitorStauts.inClineCorr = true
                            }
                            if ("1" != standAxisCorr){
                                monitorStauts.standAxisCorr = false
                            } else {
                                monitorStauts.standAxisCorr = true
                            }

                            if ("1" != collimationCorr){
                                monitorStauts.collimationCorr = false
                            } else {
                                monitorStauts.collimationCorr = true
                            }
                            if ("1" != tiltaxisCorr){
                                monitorStauts.tiltaxisCorr = false
                            } else {
                                monitorStauts.tiltaxisCorr = true
                            }

                            viewModel.updateState(monitorStauts)
                        }

                        GeoComCommon.BAP_GetPrismType.name->{
                            val list = Helper.parseJson(result.result)
                            val mirrorType = list[1]
                            Log.i("AutoCheckActivity", "棱镜类型是：$mirrorType")
                            var strType = ""
                            when(mirrorType) {
                                "0" -> strType = "圆棱镜"
                                "1" -> strType = "迷你棱镜"
                                "2" -> strType = "反射片"
                            }

                            viewModel.updateMirrorType(strType)
                        }

                        GeoComCommon.TMC_GetEdmMode.name ->{
                            val list = Helper.parseJson(result.result)
                            prismType = list[1]
                            Log.i("AutoCheckActivity", "测量模式是：$prismType")
                            var strType = ""
                            when(prismType) {
                                "0" -> strType = "标准"
                                "1" -> strType = "快速"
                                "2" -> strType = "高精"
                                "3" -> strType = "跟踪"
                            }
                            viewModel.updateMeasureModle(strType)
                        }

                        GeoComCommon.TMC_GetAngle1.name->{
                            if (result.result == "-1") {
                                monitorStauts.mIncline = false
                            } else {
                                val list = Helper.parseJson(result.result)
                                val crossIncline = list[5]      //双精度横向倾角（单位：弧度）
                                val lengthIncline = list[6]     //双精度横向倾角（单位：弧度）
                                val strT = Helper.radiansToDMSString(crossIncline.toDouble())
                                val strL = Helper.radiansToDMSString(lengthIncline.toDouble())

                                val secT = Helper.radiansToSecond(crossIncline.toDouble()).absoluteValue
                                val secL = Helper.radiansToSecond(lengthIncline.toDouble()).absoluteValue

                                if (secT < 180 && secL < 180) {
                                    val msg = "L:$strL ,  T:$strT"
                                    Log.i("AutoCheckActivity", msg)
                                    monitorStauts.mIncline = true
                                } else {
                                    monitorStauts.mIncline = false
                                }
                            }
                            viewModel.updateState(monitorStauts)
                        }

                        GeoComCommon.AUT_MakePositioning.name -> {
                            if (CustomApplication.isAppInForeground) {
                                geoComHelper.startExecution(listOf(GeoComCommon.BAP_SearchTarget))
                            }
                        }

                        GeoComCommon.BAP_SearchTarget.name -> {
                            if (result.result == "-1") {
                                safeResumeWithFailure("未找到目标")
                            } else {
                                geoComHelper.startExecution(listOf(GeoComCommon.BAP_MeasDistanceAngle(prismType)))
                            }
                        }

                        GeoComCommon.BAP_MeasDistanceAngle.name -> {

                            val list = Helper.parseJson(result.result)
                            if (list.size > 1) {
                                val strHz = Helper.radiansToDMSString(list[1].toDouble())
                                val strV = Helper.radiansToDMSString(list[2].toDouble())
                                val strDist = Helper.formateDecimal(list[3].toDouble(), "#.####")
                                Log.i("AutoCheckActivity", "获取当前测点水平角度:$strHz, 垂直角：$strV, 斜距：$strDist")

                                monitorCheckPoint.checkPointHz=list[1].toDouble()
                                monitorCheckPoint.checkPointV=list[2].toDouble()
                                monitorCheckPoint.checkPointSD=list[3].toDouble()

                                geoComHelper.startExecution(listOf(GeoComCommon.TMC_GetHeight))
                            } else {
                                safeResumeWithFailure("测量结果失败")
                            }
                        }

                        GeoComCommon.TMC_GetHeight.name -> {
                            val list = Helper.parseJson(result.result)
                            Log.i("AutoCheckActivity", "当前测点棱镜高度是${list[1]} 米")
                            geoComHelper.startExecution(listOf(GeoComCommon.TMC_GetCoordinate("1", "5000")))
                        }

                        GeoComCommon.TMC_GetCoordinate.name -> {
                            val list = Helper.parseJson(result.result)
                            if (list.size > 1) {
                                val strE = Helper.formateDecimal(list[1].toDouble(), "#.####")
                                val strN = Helper.formateDecimal(list[2].toDouble(), "#.####")
                                val strZ = Helper.formateDecimal(list[3].toDouble(), "#.####")
                                Log.i("AutoCheckActivity", "获取当前测点坐标， X/北N(m):$strN, Y/东E(m)：$strE, Z/高H(m)：$strZ")

                                monitorCheckPoint.checkPointX=Helper.formateDecimal(list[2].toDouble())
                                monitorCheckPoint.checkPointY=Helper.formateDecimal(list[1].toDouble())
                                monitorCheckPoint.checkPointZ=Helper.formateDecimal(list[3].toDouble())
                                monitorCheckPoint.createTime = Helper.formatTimestamp(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss")
                                monitorCheckPoint.isChecked=true

                                safeResumeWithSuccess()
                            } else {
                                safeResumeWithFailure("测量结果失败")
                            }
                        }
                    }
                }
            }
        }
    }

    // 安全恢复协程并返回成功结果
    private fun safeResumeWithSuccess() {
        if (isResumed.compareAndSet(false, true)) {
            currentContinuation?.resume(BluetoothTaskResult.Success(HashMap<String, Any>())) {
                currentContinuation = null
            }
        }
    }

    // 安全恢复协程并返回失败结果
    private fun safeResumeWithFailure(reason: String) {
        if (isResumed.compareAndSet(false, true)) {
            currentContinuation?.resume(BluetoothTaskResult.Failure(reason)) {
                currentContinuation = null
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        geoComHelper.removeResultCallback(geoComCallback!!)
    }


    override fun getLayoutId(): Int {
        return R.layout.activity_auto_check
    }
}